package com.so206.controller;

import com.so206.plugins.pay.utils.WXPayUtil;
import com.so206.po.SystemWeb;
import com.so206.service.WebConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信消息回复
 */
@Controller
public class WxMsgController {

    private static Logger logger = LoggerFactory.getLogger(WxMsgController.class);

    @Autowired
    private WebConfigService webConfigService;

    /**
     * 接入微信
     */
    @RequestMapping("/wx_msg")
    @ResponseBody
    public void wechatconnect(HttpServletRequest request, HttpServletResponse response) throws IOException {
        SystemWeb id = webConfigService.find_by_id(1L);
        String token = id.getAuthCode();
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        try (PrintWriter out = response.getWriter()) {
            if (isGet) {
                String signature = request.getParameter("signature");// 微信加密签名
                String timestamp = request.getParameter("timestamp");// 时间戳
                String nonce = request.getParameter("nonce");// 随机数
                String echostr = request.getParameter("echostr");//随机字符串
                if (checkSignature(signature, timestamp, nonce, token)) {
                    logger.info("Connect the weixin server is successful.");
                    out.write(echostr);
                } else {
                    logger.error("Failed to verify the signature!");
                }
            } else {
                String respMessage;
                try {
                    respMessage = weixinPost(request);
                    logger.info("The request completed successfully");
                    logger.info("to weixin server " + respMessage);
                    out.write(respMessage);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("Failed to convert the message from weixin!");
                }
            }
        } catch (Exception e) {
            logger.error("Connect the weixin server is error.");
        }
    }

    /**
     * 解析消息 并回复
     */
    private String weixinPost(HttpServletRequest request) throws Exception {
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        HashMap<String, String> map = new HashMap<>();
        try {
            // xml请求解析
            Map<String, String> requestMap = WXPayUtil.xmlToMap(sb.toString());
            // 发送方帐号（open_id）
            String fromUserName = requestMap.get("FromUserName");
            // 公众帐号
            String toUserName = requestMap.get("ToUserName");
            // 消息类型
            String msgType = requestMap.get("MsgType");
            // 消息内容
            String content = requestMap.get("Content");
            map.put("ToUserName", fromUserName);
            map.put("FromUserName", toUserName);
            map.put("CreateTime", System.currentTimeMillis() + "");
            map.put("MsgType", "text");
            if (msgType == null | fromUserName == null) {
                String msg = "获取失败,请联系管理员重新配置!";
                map.put("Content", msg);
            }
            if ("text".equals(msgType)) {
                if ("id".equalsIgnoreCase(content)) {
                    String msg = "您的OpenID是:\n\n" + fromUserName;
                    map.put("Content", msg);
                } else {
                    String msg = "输入id获取您的OpenID!";
                    map.put("Content", msg);
                }
            }
        } catch (Exception e) {
            logger.error("error......");
            e.printStackTrace();
        }
        return WXPayUtil.mapToXml(map);
    }

    /**
     * 消息验签
     */
    private static boolean checkSignature(String signature, String timestamp, String nonce, String token) {
        String[] arr = new String[]{token, timestamp, nonce};
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (String anArr : arr) {
            content.append(anArr);
        }
        MessageDigest md;
        String tmpStr = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return tmpStr != null && tmpStr.equals(signature.toUpperCase());
    }

    private static String byteToStr(byte[] byteArray) {
        StringBuilder strDigest = new StringBuilder();
        for (byte aByteArray : byteArray) {
            strDigest.append(byteToHexStr(aByteArray));
        }
        return strDigest.toString();
    }

    private static String byteToHexStr(byte mByte) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        String s = new String(tempArr);
        return s;
    }


}
